package com.sys.basics.controller;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sys.basics.config.annotation.SysLogAnnotation;
import com.sys.basics.entity.SysUser;
import com.sys.basics.utils.ShiroUtils;
import lombok.extern.slf4j.Slf4j;
import com.sys.basics.config.jsonRes.JsonResult;
import com.sys.basics.config.jsonRes.PageParam;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import com.sys.basics.entity.SysAttachment;
import com.sys.basics.service.SysAttachmentService;
import io.swagger.annotations.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import javax.validation.constraints.*;
import java.io.IOException;
import java.util.List;

/**
 * @author: ares
 * @date: 2021-10-08
 * @description: 附件资源表 前端控制器
 */
@Validated
@Slf4j
@Api(tags = "附件资源管理")
@RestController
@RequestMapping("/basics/sysAttachment")
public class SysAttachmentController extends AbstractController<SysAttachmentService, SysAttachment> {

    private JsonResult<List<SysAttachment>> listResult = new JsonResult<>();

    @Autowired
    SysAttachmentService sysAttachmentService;

    @SysLogAnnotation("单文件上传")
    @ApiOperation("单文件上传")
    @ApiImplicitParam(name = "parentId", value = "父目录id", defaultValue = "0", paramType = "query")
    @PostMapping("/upload/single")
    public JsonResult<String> uploadSingle(@NotNull(message = "父目录id不能为空") Long parentId,
                                           @RequestParam("file") MultipartFile file) throws IOException {
        JsonResult<String> urlResult = new JsonResult<>();
        SysAttachment parentDir = sysAttachmentService.getById(parentId);
        if (ObjectUtil.isNull(parentDir) && !parentId.toString().equals("0")) {
            return urlResult.error("父目录id无效");
        }
        String url = sysAttachmentService.uploadSingle(parentId, file);
        if (StringUtils.isNotEmpty(url)) {
            return urlResult.success("上传成功", url);
        } else {
            return urlResult.error("上传失败");
        }

    }

    @SysLogAnnotation("多文件上传")
    @ApiOperation("多文件上传")
    @ApiImplicitParam(name = "parentId", value = "父目录id", defaultValue = "0", paramType = "query")
    @PostMapping("/upload/multipart")
    public JsonResult<List<String>> uploadMultipart(@NotNull(message = "父目录id不能为空") Long parentId,
                                                    @RequestParam("file") MultipartFile[] file) throws IOException {
        JsonResult<List<String>> urlsResult = new JsonResult<>();
        SysAttachment parentDir = sysAttachmentService.getById(parentId);
        if (ObjectUtil.isNull(parentDir) && !parentId.toString().equals("0")) {
            return urlsResult.error("父目录id无效");
        }
        List<String> urls = sysAttachmentService.uploadMultipart(parentId, file);
        if (ArrayUtil.isNotEmpty(urls)) {
            return urlsResult.success("批量上传成功", urls);
        } else {
            return urlsResult.error("批量上传失败");
        }
    }

    @SysLogAnnotation("分页查询附件")
    @Override
    @ApiOperation("分页查询附件")
    public JsonResult<IPage<SysAttachment>> getPages(@RequestBody PageParam<SysAttachment> param) {
        JsonResult<IPage<SysAttachment>> returnPage = new JsonResult<IPage<SysAttachment>>();
        Page<SysAttachment> page = new Page<SysAttachment>(param.getPageNum(), param.getPageSize());
        SysAttachment attachment = param.getParam();
        SysUser userInfo = ShiroUtils.getUserInfo();
        attachment.setOrgId(userInfo.getDefaultOrgId());
        IPage<SysAttachment> pageData = sysAttachmentService.getPages(page, attachment);
        return returnPage.success(pageData);
    }

    @SysLogAnnotation("根据id查询附件tree")
    @ApiOperation("根据id查询tree")
    @ApiImplicitParam(name = "id", value = "节点id", required = true, defaultValue = "1", paramType = "query")
    @GetMapping("/getTreeById")
    public JsonResult<SysAttachment> getTreeById(@NotNull(message = "附件id不能为空") Long id) {
        return result.success("附件tree查询成功", sysAttachmentService.getTreeById(id));
    }

    @SysLogAnnotation("根据父节点id查询子附件")
    @ApiOperation("根据父节点id查询子附件")
    @ApiImplicitParam(name = "parentId", value = "父节点id", required = true, defaultValue = "0", paramType = "query")
    @GetMapping("/getChildrenByParentId")
    public JsonResult<List<SysAttachment>> getChildrenByParentId(@NotNull(message = "父附件id不能为空") Long parentId) {
        return listResult.success("附件tree查询成功", sysAttachmentService.getChildrenByParentId(parentId));
    }

    @SysLogAnnotation("根据父节点id查询附件tree")
    @ApiOperation("根据父节点id查询tree")
    @ApiImplicitParam(name = "parentId", value = "父节点id", required = true, defaultValue = "0", paramType = "query")
    @GetMapping("/getChildrenTreeByParentId")
    public JsonResult<List<SysAttachment>> getChildrenTreeByParentId(@NotNull(message = "父附件id不能为空") Long parentId) {
        return listResult.success("附件tree查询成功", sysAttachmentService.getChildrenTreeByParentId(parentId));
    }

    @SysLogAnnotation("查询附件目录树")
    @ApiOperation("查询目录树")
    @ApiImplicitParam(name = "parentId", value = "父节点id", required = true, defaultValue = "0", paramType = "query")
    @GetMapping("/getDirectoryTreeByParentId")
    public JsonResult<List<SysAttachment>> getDirectoryTreeByParentId(@NotNull(message = "父目录id不能为空") Long parentId) {
        return listResult.success("目录树查询成功", sysAttachmentService.getDirectoryTreeByParentId(parentId));
    }

    @SysLogAnnotation("创建附件目录")
    @ApiOperation("创建目录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "parentId", value = "父节点id", required = true, defaultValue = "0", paramType = "query"),
            @ApiImplicitParam(name = "name", value = "目录名称", required = true, defaultValue = "0", paramType = "query")
    })
    @PostMapping("/createDirectory")
    public JsonResult createDirectory(@NotNull(message = "父目录id不能为空") Long parentId,
                                      @NotEmpty(message = "目录名称不能为空") String name) {
        JsonResult result = new JsonResult();
        SysAttachment parentDir = sysAttachmentService.getById(parentId);
        if (ObjectUtil.isNull(parentDir) && !parentId.toString().equals("0")) {
            return result.error("父目录id无效");
        }
        SysAttachment dirByName = sysAttachmentService.getDirectoryByName(parentId, name);
        if (ObjectUtil.isNotNull(dirByName)) {
            return result.error("目录已存在");
        }
        return result.success("创建目录成功", sysAttachmentService.createDirectory(parentId, name));
    }

    @SysLogAnnotation("重命名附件目录")
    @ApiOperation("重命名目录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "节点id", required = true, defaultValue = "0", paramType = "query"),
            @ApiImplicitParam(name = "name", value = "目录名称", required = true, defaultValue = "0", paramType = "query")
    })
    @PostMapping("/reNameDirectory")
    public JsonResult reNameDirectory(@NotNull(message = "目录id不能为空") Long id,
                                      @NotEmpty(message = "目录名称不能为空") String name) {
        JsonResult result = new JsonResult();
        SysAttachment dir = sysAttachmentService.getById(id);
        if (ObjectUtil.isNull(dir)) {
            return result.error("目录不存在");
        }
        return result.success("重命名目录成功", sysAttachmentService.reNameDirectory(id, name));
    }

    @SysLogAnnotation("移动附件")
    @ApiOperation("移动附件")
    @ApiImplicitParam(name = "id", value = "目录id", required = true, defaultValue = "0", paramType = "query")
    @PostMapping("/batchMove")
    public JsonResult batchMove(@NotNull(message = "目录id不能为空") Long id,
                                @RequestBody List<Long> attachmentIds) {
        JsonResult result = new JsonResult();
        SysAttachment dir = sysAttachmentService.getById(id);
        if (ObjectUtil.isNull(dir)) {
            return result.error("目录不存在");
        }
        boolean moved = sysAttachmentService.batchMove(id, attachmentIds);
        if (moved) {
            return result.success("移动成功");
        } else {
            return result.error("移动失败");
        }
    }

    @SysLogAnnotation("删除附件(批量|递归)")
    @ApiOperation("删除附件(批量|递归)")
    @PostMapping("/batchRemove")
    public JsonResult batchRemove(@RequestBody List<Long> attachmentIds) {
        JsonResult result = new JsonResult();
        boolean removed = sysAttachmentService.batchRemove(attachmentIds);
        if (removed) {
            return result.success("删除成功");
        } else {
            return result.error("删除失败");
        }
    }

    @SysLogAnnotation("根据子节点id查询上级附件tree")
    @ApiOperation("根据子节点id查询上级tree")
    @ApiImplicitParam(name = "id", value = "子节点的id", required = true, defaultValue = "6", paramType = "query")
    @GetMapping("/getTreeByIdAsLeaf")
    public JsonResult<SysAttachment> getTreeByIdAsLeaf(@NotNull(message = "子附件id不能为空") Long id) {
        return result.success("附件tree查询成功", sysAttachmentService.getTreeByIdAsLeaf(id));
    }

    @SysLogAnnotation("根据id删除附件自身及子节点")
    @ApiOperation("根据id删除自身及子节点")
    @Override
    public JsonResult removeById(Long id) {
        boolean removed = sysAttachmentService.removeSelfAndChildrenById(id);
        if (removed) {
            result.success("删除成功");
        } else {
            result.error("删除失败");
        }
        return result;
    }
}
